package jnpf.engine.custom.cmd.jump;


import jnpf.engine.util.SpringContextHolder;
import org.flowable.bpmn.model.Activity;
import org.flowable.bpmn.model.BpmnModel;
import org.flowable.bpmn.model.MultiInstanceLoopCharacteristics;
import org.flowable.common.engine.impl.interceptor.Command;
import org.flowable.common.engine.impl.interceptor.CommandContext;
import org.flowable.engine.FlowableEngineAgenda;
import org.flowable.engine.delegate.DelegateExecution;
import org.flowable.engine.impl.bpmn.behavior.MultiInstanceActivityBehavior;
import org.flowable.engine.impl.persistence.deploy.DeploymentManager;
import org.flowable.engine.impl.persistence.entity.DeploymentEntityManager;
import org.flowable.engine.impl.persistence.entity.ExecutionEntity;
import org.flowable.engine.impl.persistence.entity.ExecutionEntityManager;
import org.flowable.engine.impl.util.CommandContextUtil;
import org.flowable.engine.impl.util.ProcessDefinitionUtil;
import org.flowable.engine.repository.ProcessDefinition;
import org.flowable.spring.SpringProcessEngineConfiguration;
import org.flowable.task.service.TaskService;
import org.flowable.task.service.impl.persistence.entity.TaskEntity;
import org.flowable.task.service.impl.persistence.entity.TaskEntityManager;

import java.io.Serializable;

/**
 *
 */
public class DeleteMulitiInstanceExecutionCmd implements Command<Void>, Serializable {
	protected final String NUMBER_OF_INSTANCES = "nrOfInstances";
	protected final String NUMBER_OF_ACTIVE_INSTANCES = "nrOfActiveInstances";
	protected final String NUMBER_OF_COMPLETED_INSTANCES = "nrOfCompletedInstances";
	protected String collectionElementIndexVariable = "loopCounter";
	/**
	 * 任务id
	 */
	private String taskId;
	/**
	 * 是否正常完成当前的节点的标识位 传递为true就行
	 */
	private boolean executionIsCompleted;

	/**
	 *
	 * @param executionIsCompleted 是否正常完成当前的节点的标识位 传递为true就行
	 * @param taskId 任务id
	 */
	public DeleteMulitiInstanceExecutionCmd(boolean executionIsCompleted, String taskId) {
		this.executionIsCompleted = executionIsCompleted;
		this.taskId = taskId;
	}

	@Override
	public Void execute(CommandContext commandContext) {
		SpringProcessEngineConfiguration springProcessEngineConfiguration = SpringContextHolder.getBean(SpringProcessEngineConfiguration.class);
		TaskEntityManager taskEntityManager = springProcessEngineConfiguration.getTaskServiceConfiguration().getTaskEntityManager();

		TaskEntity taskEntity = taskEntityManager.findById(taskId);

		// 获取执行实例管理器
		ExecutionEntityManager executionEntityManager = CommandContextUtil.getExecutionEntityManager();
		// 获取执行实例 三级树
		ExecutionEntity execution = executionEntityManager.findById(taskEntity.getExecutionId());
		String processDefinitionId = execution.getProcessDefinitionId();
		// 获取当前实例中的数据，因为我们要获取当前的节点，并判断是否是多实例任务节点
		BpmnModel bpmnModel = ProcessDefinitionUtil.getBpmnModel(processDefinitionId);
		Activity miActivityElement = (Activity) bpmnModel.getFlowElement(execution.getCurrentActivityId());
		MultiInstanceLoopCharacteristics loopCharacteristics = miActivityElement.getLoopCharacteristics();
		if (loopCharacteristics == null) {
			throw new RuntimeException("没有找到MultiInstanceLoopCharacteristics");
		}
		if (!(miActivityElement.getBehavior() instanceof MultiInstanceActivityBehavior)) {
			throw new RuntimeException("这个节点不是多实例节点");
		}
		DeploymentManager deploymentManager = springProcessEngineConfiguration.getDeploymentManager();
		ProcessDefinition processDefinition = null;
		if (processDefinitionId != null) {
			processDefinition = deploymentManager.findDeployedProcessDefinitionById(processDefinitionId);
			if (processDefinition == null) {
				throw new RuntimeException("找不到流程定义");
			}
		}
//		if (Activiti5Util.isActiviti5ProcessDefinition(commandContext, processDefinition)) {
//			throw new RuntimeException("当前的减签类不支持5版本");
//		}
		// 获取执行实例 二级树
		ExecutionEntity secondExecutionEntity = execution.getParent();
		if (loopCharacteristics.isSequential()) {

		} else {
			executionEntityManager.deleteChildExecutions(execution, "shareniu_Delete", false);
			executionEntityManager.deleteExecutionAndRelatedData(execution, "shareniu_Delete", true);
		}

		// 更新变量表数据
		int loopCounter = 0;
		// 串行多实例
		if (loopCharacteristics.isSequential()) {
			loopCounter = getLoopVariable(execution, collectionElementIndexVariable);
		}

		if (!loopCharacteristics.isSequential()) {
			Integer variable = (Integer) secondExecutionEntity.getVariable(NUMBER_OF_ACTIVE_INSTANCES);
			secondExecutionEntity.setVariableLocal(NUMBER_OF_ACTIVE_INSTANCES, variable - 1);
		}
		if (executionIsCompleted) {
			// 获取这个 NUMBER_OF_COMPLETED_INSTANCES
			Integer variable = (Integer) secondExecutionEntity.getVariable(NUMBER_OF_COMPLETED_INSTANCES);
			secondExecutionEntity.setVariableLocal(NUMBER_OF_COMPLETED_INSTANCES, variable + 1);
			loopCounter++;
			execution.setVariableLocal(collectionElementIndexVariable, loopCounter);
		} else {
			Integer variable = (Integer) secondExecutionEntity.getVariable(NUMBER_OF_INSTANCES);
			secondExecutionEntity.setVariableLocal(NUMBER_OF_INSTANCES, variable - 1);
		}
		if (taskId != null) {
			taskEntityManager.delete(taskId);
		}
		// 触发实例运转
		FlowableEngineAgenda agenda = CommandContextUtil.getAgenda();
		agenda.planContinueProcessInCompensation(execution);

		return null;
	}

	protected Integer getLoopVariable(DelegateExecution execution, String variableName) {
		Object value = execution.getVariableLocal(variableName);
		DelegateExecution parent = execution.getParent();
		while (value == null && parent != null) {
			value = parent.getVariableLocal(variableName);
			parent = parent.getParent();
		}
		return (Integer) (value != null ? value : 0);
	}
}
